#include "Application.h"
#include "Helpers.h"
#include <iostream>
#include "LocalServer.h"
#include "RemoteServer.h"

cat::Application cat::Application::_instance; 

cat::Application::Application(void)
{
	_window = NULL;
	_server = NULL;
}


cat::Application::~Application(void)
{
	DELETE_LIST_ITEMS(_controllers, cat::ControllerBase)
	DELETE_LIST_ITEMS(_tanks, cat::Tank)
	if(_window != NULL) delete _window;
	if(_server != NULL) delete _server;
}

cat::Application& cat::Application::current(void)
{
	return _instance;
}

sf::RenderWindow& cat::Application::getWindow(void)
{
	return *_window;
}

std::list<cat::ControllerBase*>::iterator cat::Application::getControllersIteratorBegin(void)
{
	return _controllers.begin();
}

std::list<cat::ControllerBase*>::iterator cat::Application::getControllersIteratorEnd(void)
{
	return _controllers.end();
}

void cat::Application::registerController(cat::ControllerBase* controller)
{
	_controllers.push_back(controller);
}

std::list<cat::Tank*>::iterator cat::Application::getTanksIteratorBegin(void)
{
	return _tanks.begin();
}

std::list<cat::Tank*>::iterator cat::Application::getTanksIteratorEnd(void)
{
	return _tanks.end();
}

void cat::Application::registerTank(cat::Tank* tank)
{
	_tanks.push_back(tank);
}

cat::BulletFactory& cat::Application::getBulletFactory(void)
{
	return _bulletFactory;
}

cat::ServerBase& cat::Application::getServer(void)
{
	return *_server;
}

void cat::Application::menu(void)
{
	std::string login;

	do
	{
		std::cout << "Enter your name > ";
		std::cin >> login;
		std::cout << std::endl;
	} while(login.empty());

	std::cout << std::endl << "Welcome to CaT game " << login << "!" << std::endl << std::endl;

	int serverAnswer = 1;
	std::cout << "Choose an action" << std::endl
		<< "1 - Create a server" << std::endl
		<< "2 - Join a server" << std::endl 
		<< "> ";

	std::cin >> serverAnswer;
	std::cout << std::endl << std::endl;

	if(serverAnswer == 1)
	{
		_server = new LocalServer(54000);
		_server->connect();
	}
	else if(serverAnswer == 2)
	{
		std::string serverAdress;
		
		std::cout << "Adress of the server > ";
		std::cin >> serverAdress;
		_server = new RemoteServer(serverAdress, 54000);
		_server->connect();
	}

	if(_window == NULL)
	{
		sf::ContextSettings settings(0u, 0u, 8u, 2u, 0u);
		_window = new sf::RenderWindow(sf::VideoMode(800, 600), "CaT - bench1", 7u, settings);
		//_window->setVerticalSyncEnabled(true);
		_window->setFramerateLimit(60);
	}
}

cat::ControllerBase* cat::Application::popControllerRequieringSynchronization(void)
{
	cat::ControllerBase* controller = NULL;
	if(!_controllersRequieringSynchronization.empty())
	{
		controller = _controllersRequieringSynchronization.top();
		_controllersRequieringSynchronization.pop();
	}
	
	return controller;
}

void cat::Application::pushControllerRequieringSynchronization(cat::ControllerBase* controller)
{
	_controllersRequieringSynchronization.push(controller);
}